﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using LitJson;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using static DMC300Axis_IO.Function.DMC300_Info;
using System.Runtime.InteropServices.ComTypes;
using MvCameraControl;
using OCR.Config;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using OCR.SystemThread;

namespace OCR
{
    internal class AlgorithmModule
    {
        [DllImport(@"ocr.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void do_ocr(string inputImgDir, string outputImgDir);
        public static void ImageHandle(string inputDir, string outputDir)
        {
            try
            {
                do_ocr(inputDir, outputDir);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error: {ex.Message}");
                //Console.WriteLine($"Error: {ex.Message}");
            }

            //Console.ReadKey();
            //MessageBox.Show("OCR processing completed.");
            //Console.WriteLine("OCR processing completed.");

        }

        // 导入 C++ DLL 函数  //ocr_v2  -cpu_ocr  cpu_ocr_v4  cpu_ocr  ocr_v4_gpu
        [DllImport(@"ocr_v2.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void CreateInstance();
        [DllImport(@"ocr_v2.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr do_ocr(byte[] imageData, int width, int height);
        [DllImport(@"cpu_ocr_v4.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr do_ocr_Mat(IntPtr img);
        [DllImport(@"ocr_v2.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void DestroyInstance();

        public static List<List<Point>> pointsList = new List<List<Point>>();
        public static void ImageHandleV2()
        {
            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            if (CameraReceiveThread.frameForSave == null)
            {
                Console.WriteLine("无图像信息");
                return;
            }
            //IntPtr resultPtr = do_ocr(Camera_Form.frameForSave.Image.PixelData, (int)Camera_Form.frameForSave.Image.Width, (int)Camera_Form.frameForSave.Image.Height);
            Console.WriteLine("frameForSave.Image1:  " + CameraReceiveThread.frameForSave.Image);
            //Console.WriteLine("image:  "+ image);
            //if (image == null)
            //    return;

            //SaveWrongImg(CameraReceiveThread.frameForSave.Image.ToBitmap());
            IntPtr resultPtr = do_ocr(CameraReceiveThread.frameForSave.Image.PixelData, (int)CameraReceiveThread.frameForSave.Image.Width, (int)CameraReceiveThread.frameForSave.Image.Height);

            //IntPtr resultPtr = do_ocr(image.PixelData, (int)image.Width, (int)image.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);
            DateTime dt2 = DateTime.Now;
            Console.WriteLine("间隔: "+(dt2 - dt1).Milliseconds);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                //Console.WriteLine(configs[i].text);
                //MessageBox.Show(configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    //Console.WriteLine("X:  "+configs[i].box[j][0]+"    Y:  " + configs[i].box[j][1]);
                    Point point = new Point(configs[i].box[j][0] , configs[i].box[j][1] );
                    points.Add(point);
                }
                pointsList.Add(points);
            }

            currConfigs = configs;
            LocalCompare(pointsList);

            Console.WriteLine("图片信息个数： "+pointsList.Count);
            DateTime dt3 = DateTime.Now;
            Console.WriteLine("Json解析间隔: " + (dt3 - dt2).Milliseconds);

        }
        public static void ImageHandleV2_Modbus_Zoom()
        {
            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            Console.WriteLine("缩放frameForSave.Image1:  " + CameraReceiveThread.frameForSave.Image);

            Rectangle cropRect = new Rectangle
(int.Parse(LocalTemplateInfo.rect_X) * 2,
int.Parse(LocalTemplateInfo.rect_Y) * 2,
(int.Parse(LocalTemplateInfo.rect_Right) - int.Parse(LocalTemplateInfo.rect_X)) * 2,
(int.Parse(LocalTemplateInfo.rect_Bottom) - int.Parse(LocalTemplateInfo.rect_Y)) * 2);
            OCR_Form.oCR_Form.mainCameraPb.Image = AlgorithmModule.CropImage(CameraReceiveThread.frameForSave.Image.ToBitmap(), cropRect, "cropTest.bmp");
            
            DateTime dt2 = DateTime.Now;


            OCR_Form.oCR_Form.InfoTB_01.Text = OCR_Form.oCR_Form.InfoTB_02.Text = OCR_Form.oCR_Form.InfoTB_03.Text = OCR_Form.oCR_Form.InfoTB_04.Text
                = OCR_Form.oCR_Form.InfoTB_05.Text = OCR_Form.oCR_Form.InfoTB_06.Text = string.Empty;
            if (currConfigs.Count >= 1)
                OCR_Form.oCR_Form.InfoTB_01.Text = currConfigs[0].text;
            if (currConfigs.Count >= 2)
                OCR_Form.oCR_Form.InfoTB_02.Text = currConfigs[1].text;
            if (currConfigs.Count >= 3)
                OCR_Form.oCR_Form.InfoTB_03.Text = currConfigs[2].text;
            if (currConfigs.Count >= 4)
                OCR_Form.oCR_Form.InfoTB_04.Text = currConfigs[3].text;
            if (currConfigs.Count >= 5)
                OCR_Form.oCR_Form.InfoTB_05.Text = currConfigs[4].text;
            if (currConfigs.Count >= 6)
                OCR_Form.oCR_Form.InfoTB_06.Text = currConfigs[5].text;

            if (OCR_Form.softwareType == "1")
            {
                OCR_Form.oCR_Form.InfoTB_01_Modbus.Text
                    = OCR_Form.oCR_Form.InfoTB_02_Modbus.Text
                    = OCR_Form.oCR_Form.InfoTB_03_Modbus.Text
                    = OCR_Form.oCR_Form.InfoTB_04_Modbus.Text
                    = OCR_Form.oCR_Form.InfoTB_05_Modbus.Text
                    = OCR_Form.oCR_Form.InfoTB_06_Modbus.Text = string.Empty;
                if (currConfigs.Count >= 1 & LocalTemplateInfo.Info01 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_01_Modbus.Text = currConfigs[0].text;
                if (currConfigs.Count >= 2 & LocalTemplateInfo.Info02 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_02_Modbus.Text = currConfigs[1].text;
                if (currConfigs.Count >= 3 & LocalTemplateInfo.Info03 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_03_Modbus.Text = currConfigs[2].text;
                if (currConfigs.Count >= 4 & LocalTemplateInfo.Info04 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_04_Modbus.Text = currConfigs[3].text;
                if (currConfigs.Count >= 5 & LocalTemplateInfo.Info05 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_05_Modbus.Text = currConfigs[4].text;
                if (currConfigs.Count >= 6 & LocalTemplateInfo.Info06 != string.Empty)
                    OCR_Form.oCR_Form.InfoTB_06_Modbus.Text = currConfigs[5].text;
            }

            if (!File.Exists("ImageResult.txt"))
            {
                File.WriteAllText("ImageResult.txt", null, Encoding.UTF8);
            }

            try
            {
                StreamWriter sw = File.AppendText("ImageResult.txt");
                sw.WriteLine(DateTime.Now.ToString("缩放记录时间：" + "yyyy:MM:dd:HH:mm:ss.fffffff") + "  " + "进算法：" + dt1.TimeOfDay + "  " + "出算法：" + dt2.TimeOfDay + "  " + "算法间隔：" + (dt2 - dt1).Milliseconds);//yyyy:MM:dd:HH:mm:ss.fffff
                sw.Close();
            }
            catch (Exception e)
            {

                throw e;
            }
            bool isSame = LocalTemplateInfo.CompareTemplate(AlgorithmModule.currConfigs);
            Console.WriteLine(isSame);
            if (!isSame)
            {
                Console.WriteLine("缩放NG");
                OCR_Form.oCR_Form.tbNGResult1.Text = "NG";
                OCR_Form.ModbusSendNg();


                //NG存图
                Console.WriteLine("缩放NG存图");
                try
                {
                    string outImgPath = Application.StartupPath + "\\out\\";
                    string tempPath = outImgPath + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
                    Console.WriteLine(Directory.Exists(tempPath));
                    if (!Directory.Exists(tempPath))
                    {
                        Directory.CreateDirectory(tempPath);
                    }
                    Console.WriteLine(tempPath);
                    CameraReceiveThread.frameForSave.Image.ToBitmap().Save(tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_NG" + ".bmp");
                    AlgorithmModule.RectPoints(CameraReceiveThread.frameForSave.Image.ToBitmap()).Save(tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_NG_A" + ".bmp");
                    //CameraReceiveThread.frameForSave.Image.ToBitmap().Save(@"out\\" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_NG" + ".bmp");
                    //AlgorithmModule.RectPoints(CameraReceiveThread.frameForSave.Image.ToBitmap()).Save(@"out\\" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_NG_A" + ".bmp");
                }
                catch (Exception e)
                {
                    throw (e);
                }
            }
            else
            {
                string outImgPath = Application.StartupPath + "\\out\\";
                string tempPath = outImgPath + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
                Console.WriteLine(Directory.Exists(tempPath));
                if (!Directory.Exists(tempPath))
                {
                    Directory.CreateDirectory(tempPath);
                }
                Console.WriteLine("缩放OK");
                OCR_Form.oCR_Form.tbNGResult1.Text = "OK";
                if (OCR_Form.oCR_Form.saveImgCb_PLC.Checked || OCR_Form.oCR_Form.saveOKImgcB.Checked)
                {
                    //OK存图
                    Console.WriteLine("缩放ok存图");
                    try
                    {
                        CameraReceiveThread.frameForSave.Image.ToBitmap().Save(tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_OK" + ".bmp");
                        AlgorithmModule.RectPoints(CameraReceiveThread.frameForSave.Image.ToBitmap()).Save(tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_OK_A" + ".bmp");

                    }
                    catch (Exception e)
                    {
                        throw (e);
                    }
                }
            }
            //SaveBmp();
        }
        public static List<TemplateConfig> currConfigs = new List<TemplateConfig>();
        public static void ImageHandleV2(string path)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {                
                Console.WriteLine("算法图片信息"+i+": "+configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0] , configs[i].box[j][1] );
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;


            //RectPoints(bitmap);
        }
        public static void ImageHandleV2(Bitmap bitmap)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            //System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;

            LocalCompare(pointsList);
            //RectPoints(bitmap);
        }
        public static void ImageHandleV2_Camera()
        {
            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            IntPtr resultPtr = do_ocr(Camera_Form.frameForSave.Image.PixelData, (int)Camera_Form.frameForSave.Image.Width, (int)Camera_Form.frameForSave.Image.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);
            DateTime dt2 = DateTime.Now;
            Console.WriteLine("间隔: " + (dt2 - dt1).Milliseconds);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                //Console.WriteLine(configs[i].text);
                //MessageBox.Show(configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    //Console.WriteLine("X:  "+configs[i].box[j][0]+"    Y:  " + configs[i].box[j][1]);
                    Point point = new Point(configs[i].box[j][0] , configs[i].box[j][1] );
                    points.Add(point);
                }
                pointsList.Add(points);
            }

            Console.WriteLine("图片信息个数： " + pointsList.Count);

            DateTime dt3 = DateTime.Now;
            Console.WriteLine("Json解析间隔: " + (dt3 - dt2).Milliseconds);
            OCR_Form.camera_Form.CameraPB.Image = RectPoints(Camera_Form.frameForSave.Image.ToBitmap());
            OCR_Form.camera_Form.CameraPB.SizeMode = PictureBoxSizeMode.Zoom;
            OCR_Form.camera_Form.CameraPB.BackgroundImageLayout = ImageLayout.Zoom;


            //if (!File.Exists("ImageResult.txt"))
            //{
            //    File.WriteAllText("ImageResult.txt", null, Encoding.UTF8);
            //}

            //try
            //{
            //    StreamWriter sw = File.AppendText("ImageResult.txt");
            //    sw.WriteLine(DateTime.Now.ToString("记录时间：" + "yyyy:MM:dd:HH:mm:ss.fffffff") + "  " + "进算法：" + dt1.TimeOfDay + "  " + "出算法：" + dt2.TimeOfDay + "  " + "算法间隔：" + (dt2 - dt1).Milliseconds + "   " + result);//yyyy:MM:dd:HH:mm:ss.fffff
            //    sw.Close();
            //}
            //catch (Exception e)
            //{

            //    throw e;
            //}

        }
        public static void ImageHandleV2_Template()
        {

            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            try
            {
                if (CameraReceiveThread.frameForSave == null)
                {
                    Console.WriteLine("无图像信息");
                    return;
                }
                IntPtr resultPtr = do_ocr(CameraReceiveThread.frameForSave.Image.PixelData, (int)CameraReceiveThread.frameForSave.Image.Width, (int)CameraReceiveThread.frameForSave.Image.Height);
                string result = Marshal.PtrToStringAnsi(resultPtr);
                DateTime dt2 = DateTime.Now;
                Console.WriteLine("间隔: " + (dt2 - dt1).Milliseconds);

                byte[] rebytes = Encoding.Default.GetBytes(result);
                result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

                Console.WriteLine("OCR Result:\n" + result);

                List<TemplateConfig> configs = new List<TemplateConfig>();
                configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

                for (int i = 0; i < configs.Count; i++)
                {
                    //Console.WriteLine(configs[i].text);
                    List<Point> points = new List<Point>();
                    for (int j = 0; j < configs[i].box.Count; j++)
                    {
                        //Console.WriteLine("X:  "+configs[i].box[j][0]+"    Y:  " + configs[i].box[j][1]);
                        Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                        points.Add(point);
                    }
                    pointsList.Add(points);
                }
                currConfigs.Clear();
                currConfigs = configs;
                Console.WriteLine("图片信息个数： " + pointsList.Count);

                DateTime dt3 = DateTime.Now;
                Console.WriteLine("Json解析间隔: " + (dt3 - dt2).Milliseconds);
                OCR_Form.template_Form.Template_pB.Image = RectPoints(CameraReceiveThread.frameForSave.Image.ToBitmap(), false);
                OCR_Form.template_Form.Template_pB.SizeMode = PictureBoxSizeMode.Zoom;
                OCR_Form.template_Form.Template_pB.BackgroundImageLayout = ImageLayout.Zoom;

                Template_Form.cameraRecvBitmap = CameraReceiveThread.frameForSave.Image.ToBitmap();

                //try
                //{
                //    if (CameraReceiveThread.frameForSave == null)
                //    {
                //        Console.WriteLine("存图时无图像信息");
                //        return;
                //    }

                //    ImageFormatInfo imageFormatInfo = new ImageFormatInfo();
                //    imageFormatInfo.FormatType = ImageFormatType.Bmp;
                //    string ImagePath = @"TemplateInput\\TemplateOrigin.bmp";
                //    CameraReceiveThread.device.ImageSaver.SaveImageToFile(ImagePath, CameraReceiveThread.frameForSave.Image, imageFormatInfo, CFAMethod.Equilibrated);
                //    Template_Form.currPath = ImagePath;
                //}
                //catch (Exception ex)
                //{
                //    throw (ex);
                //}


                Template_Form.pointsList = AlgorithmModule.pointsList;

                OCR_Form.template_Form.InfoTB_01.Text = OCR_Form.template_Form.InfoTB_02.Text 
                    = OCR_Form.template_Form.InfoTB_03.Text = OCR_Form.template_Form.InfoTB_04.Text 
                    = OCR_Form.template_Form.InfoTB_05.Text = OCR_Form.template_Form.InfoTB_06.Text = string.Empty;
                if (AlgorithmModule.currConfigs.Count >= 1)
                    OCR_Form.template_Form.InfoTB_01.Text = AlgorithmModule.currConfigs[0].text;
                if (AlgorithmModule.currConfigs.Count >= 2)
                    OCR_Form.template_Form.InfoTB_02.Text = AlgorithmModule.currConfigs[1].text;
                if (AlgorithmModule.currConfigs.Count >= 3)
                    OCR_Form.template_Form.InfoTB_03.Text = AlgorithmModule.currConfigs[2].text;
                if (AlgorithmModule.currConfigs.Count >= 4)
                    OCR_Form.template_Form.InfoTB_04.Text = AlgorithmModule.currConfigs[3].text;
                if (AlgorithmModule.currConfigs.Count >= 5)
                    OCR_Form.template_Form.InfoTB_05.Text = AlgorithmModule.currConfigs[4].text;
                if (AlgorithmModule.currConfigs.Count >= 6)
                    OCR_Form.template_Form.InfoTB_06.Text = AlgorithmModule.currConfigs[5].text;

            }
            catch (Exception e)
            {
                throw (e);
            }
            




        }
        public static bool isOnceTri_Modbus;
        public static void ImageHandleV2_OnceTri_Modbus()
        {

            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            try
            {
                if (CameraReceiveThread.frameForSave == null)
                {
                    Console.WriteLine("无图像信息");
                    return;
                }
                IntPtr resultPtr = do_ocr(CameraReceiveThread.frameForSave.Image.PixelData, (int)CameraReceiveThread.frameForSave.Image.Width, (int)CameraReceiveThread.frameForSave.Image.Height);
                string result = Marshal.PtrToStringAnsi(resultPtr);
                DateTime dt2 = DateTime.Now;
                Console.WriteLine("间隔: " + (dt2 - dt1).Milliseconds);

                byte[] rebytes = Encoding.Default.GetBytes(result);
                result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

                Console.WriteLine("OCR Result:\n" + result);

                List<TemplateConfig> configs = new List<TemplateConfig>();
                configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

                for (int i = 0; i < configs.Count; i++)
                {
                    //Console.WriteLine(configs[i].text);
                    List<Point> points = new List<Point>();
                    for (int j = 0; j < configs[i].box.Count; j++)
                    {
                        //Console.WriteLine("X:  "+configs[i].box[j][0]+"    Y:  " + configs[i].box[j][1]);
                        Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                        points.Add(point);
                    }
                    pointsList.Add(points);
                }
                currConfigs.Clear();
                currConfigs = configs;
                Console.WriteLine("图片信息个数： " + pointsList.Count);

                DateTime dt3 = DateTime.Now;
                Console.WriteLine("Json解析间隔: " + (dt3 - dt2).Milliseconds);
                OCR_Form.oCR_Form.mainCameraPb.Image = RectPoints(CameraReceiveThread.frameForSave.Image.ToBitmap(), true);
                OCR_Form.oCR_Form.mainCameraPb.SizeMode = PictureBoxSizeMode.Zoom;
                OCR_Form.oCR_Form.mainCameraPb.BackgroundImageLayout = ImageLayout.Zoom;

                if (OCR_Form.softwareType == "1")
                {
                    OCR_Form.oCR_Form.InfoTB_01_Modbus.Text
                        = OCR_Form.oCR_Form.InfoTB_02_Modbus.Text
                        = OCR_Form.oCR_Form.InfoTB_03_Modbus.Text
                        = OCR_Form.oCR_Form.InfoTB_04_Modbus.Text
                        = OCR_Form.oCR_Form.InfoTB_05_Modbus.Text
                        = OCR_Form.oCR_Form.InfoTB_06_Modbus.Text = string.Empty;
                    if (configs.Count >= 1 & LocalTemplateInfo.Info01 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_01_Modbus.Text = configs[0].text;
                    if (configs.Count >= 2 & LocalTemplateInfo.Info02 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_02_Modbus.Text = configs[1].text;
                    if (configs.Count >= 3 & LocalTemplateInfo.Info03 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_03_Modbus.Text = configs[2].text;
                    if (configs.Count >= 4 & LocalTemplateInfo.Info04 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_04_Modbus.Text = configs[3].text;
                    if (configs.Count >= 5 & LocalTemplateInfo.Info05 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_05_Modbus.Text = configs[4].text;
                    if (configs.Count >= 6 & LocalTemplateInfo.Info06 != string.Empty)
                        OCR_Form.oCR_Form.InfoTB_06_Modbus.Text = configs[5].text;
                }
                //isOnceTri_Modbus = true;
            }
            catch (Exception e)
            {
                throw (e);
            }





        }
        public static void ImageHandleV2_Template_LocalImg()
        {

            pointsList.Clear();
            DateTime dt1 = DateTime.Now;
            IntPtr resultPtr = do_ocr(Template_Form.frameForSave.Image.PixelData, (int)Template_Form.frameForSave.Image.Width, (int)Template_Form.frameForSave.Image.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);
            DateTime dt2 = DateTime.Now;
            Console.WriteLine("间隔: " + (dt2 - dt1).Milliseconds);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                //Console.WriteLine(configs[i].text);
                //MessageBox.Show(configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    //Console.WriteLine("X:  "+configs[i].box[j][0]+"    Y:  " + configs[i].box[j][1]);
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs.Clear();
            currConfigs = configs;
            Console.WriteLine("图片信息个数： " + pointsList.Count);

            DateTime dt3 = DateTime.Now;
            Console.WriteLine("Json解析间隔: " + (dt3 - dt2).Milliseconds);
            OCR_Form.template_Form.Template_pB.Image = RectPoints(Template_Form.frameForSave.Image.ToBitmap(), false);
            OCR_Form.template_Form.Template_pB.SizeMode = PictureBoxSizeMode.Zoom;
            OCR_Form.template_Form.Template_pB.BackgroundImageLayout = ImageLayout.Zoom;

            //try
            //{

            //    string ImagePath = @"TemplateInput\\TemplateOrigin.bmp";
            //    if (File.Exists(ImagePath))
            //    {
            //        File.Delete(ImagePath);
            //    }
            //    RectPoints(Template_Form.frameForSave.Image.ToBitmap()).Save(ImagePath);
            //}
            //catch (Exception ex)
            //{
            //    //throw (ex);
            //}
            //try
            //{
            //    ImageFormatInfo imageFormatInfo = new ImageFormatInfo();
            //    imageFormatInfo.FormatType = ImageFormatType.Bmp;
            //    string ImagePath = @"TemplateInput\\TemplateOrigin.bmp";
            //    Template_Form.device.ImageSaver.SaveImageToFile(ImagePath, Template_Form.frameForSave.Image, imageFormatInfo, CFAMethod.Equilibrated);
            //}
            //catch (Exception ex)
            //{
            //    throw (ex);
            //}

            //if (!File.Exists("ImageResult.txt"))
            //{
            //    File.WriteAllText("ImageResult.txt", null, Encoding.UTF8);
            //}

            //try
            //{
            //    StreamWriter sw = File.AppendText("ImageResult.txt");
            //    sw.WriteLine(DateTime.Now.ToString("记录时间：" + "yyyy:MM:dd:HH:mm:ss.fffffff") + "  " + "进算法：" + dt1.TimeOfDay + "  " + "出算法：" + dt2.TimeOfDay + "  " + "算法间隔：" + (dt2 - dt1).Milliseconds + "   " + result);//yyyy:MM:dd:HH:mm:ss.fffff
            //    sw.Close();
            //}
            //catch (Exception e)
            //{

            //    throw e;
            //}

        }
        public static void ImageHandleV2_Refresh(string path)
        {
            pointsList.Clear();
            // 读取本地图片
            System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //List<TemplateConfig> configs = new List<TemplateConfig>();
            //configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            //for (int i = 0; i < configs.Count; i++)
            //{
            //    List<Point> points = new List<Point>();
            //    for (int j = 0; j < configs[i].box.Count; j++)
            //    {
            //        Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
            //        points.Add(point);
            //    }
            //    pointsList.Add(points);
            //}
            //currConfigs = configs;
        }
        public static Image RectPoints()
        {
            //Bitmap bitmap = new Bitmap(Camera_Form.frameForSave.Image.ToBitmap());
            Bitmap bitmap = new Bitmap(CameraReceiveThread.frameForSave.Image.ToBitmap());

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);
            foreach (var item in pointsList)
            {
                graphics1.DrawLines(pen, item.ToArray());
                graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            }

            graphics1.Dispose();

            return bitmap;
        }
        public static Image RectPoints(string path)
        {
            //Bitmap bitmap = new Bitmap(Camera_Form.frameForSave.Image.ToBitmap());

            Image originImg = Image.FromFile(path);

            Bitmap bitmap = new Bitmap(originImg, originImg.Width, originImg.Height);

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);
            foreach (var item in pointsList)
            {
                graphics1.DrawLines(pen, item.ToArray());
                graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            }

            graphics1.Dispose();

            return bitmap;
        }
        public static Image RectPoints(Image bitmapInput,bool isLocalCompare=true)
        {
            Bitmap bitmap = new Bitmap(bitmapInput);

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);

            if (isLocalCompare)
            {
                List<bool> inside = new List<bool>();
                bool isInsideRect = true;
                foreach (var item in pointsList)
                {
                    foreach (var x in item)
                    {
                        bool x_Inside = int.Parse(LocalTemplateInfo.rect_X) * 2 <= x.X & x.X <= int.Parse(LocalTemplateInfo.rect_Right) * 2;
                        bool y_Inside = int.Parse(LocalTemplateInfo.rect_Y) * 2 <= x.Y & x.Y <= int.Parse(LocalTemplateInfo.rect_Bottom) * 2;
                        Console.WriteLine("x: " + x_Inside.ToString() + "  y: " + y_Inside.ToString() + "  x&y: " + (x_Inside & y_Inside).ToString());
                        if (!(x_Inside & y_Inside))
                        {
                            isInsideRect = false;
                            break;
                        }
                        else
                        {
                            isInsideRect = true;
                        }
                    }
                    inside.Add(isInsideRect);
                }
                for (int i = 0; i < inside.Count; i++)
                {
                    if (inside[i])
                    {
                        graphics1.DrawLines(pen, pointsList[i].ToArray());
                        graphics1.DrawLine(pen, pointsList[i].ToArray()[0], pointsList[i].ToArray()[3]);
                    }
                }
            }
            else
            {
                foreach (var item in pointsList)
                {
                    graphics1.DrawLines(pen, item.ToArray());
                    graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
                }
            }

            graphics1.Dispose();

            return bitmap;
        }

        public static Image RectPoints(string path, List<List<Point>> pointsList)
        {
            //Bitmap bitmap = new Bitmap(Camera_Form.frameForSave.Image.ToBitmap());

            Image originImg = Image.FromFile(path);

            Bitmap bitmap = new Bitmap(originImg, originImg.Width, originImg.Height);

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);
            foreach (var item in pointsList)
            {
                graphics1.DrawLines(pen, item.ToArray());
                graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            }

            graphics1.Dispose();

            return bitmap;
        }

        public static Image RectPoints(Bitmap bitmap, List<List<Point>> pointsList)
        {
            //Console.WriteLine("bitmap.Size: "+bitmap.Size);

            //Bitmap bitmap = new Bitmap(bitmapInput);
            Bitmap convertedImage = new Bitmap(
            bitmap.Width,
            bitmap.Height,
            PixelFormat.Format32bppArgb);

            using (Graphics g = Graphics.FromImage(convertedImage))
            {
                g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height);
            }

            Graphics graphics1 = Graphics.FromImage(convertedImage);

            Pen pen = new Pen(Color.Green, 5);

            for (int i = 0; i < pointsList.Count; i++)
            {
                graphics1.DrawLines(pen, pointsList[i].ToArray());
                graphics1.DrawLine(pen, pointsList[i].ToArray()[0], pointsList[i].ToArray()[3]);
            }

            graphics1.Dispose();
            return convertedImage;
        }
        public static List<string> mainInfos = new List<string>();
        public static List<List<Point>> finalPointList = new List<List<Point>>();
        public static void LocalCompare(List<List<Point>> pointsList)
        {
            mainInfos.Clear();
            finalPointList.Clear();
            List<bool> inside = new List<bool>();
            bool isInsideRect = true;
            Console.WriteLine("识别框个数：" + pointsList.Count);
            foreach (var item in pointsList)
            {
                foreach (var x in item)
                {
                    bool x_Inside = int.Parse(LocalTemplateInfo.rect_X) * 2 <= x.X & x.X <= int.Parse(LocalTemplateInfo.rect_Right) * 2;
                    bool y_Inside = int.Parse(LocalTemplateInfo.rect_Y) * 2 <= x.Y & x.Y <= int.Parse(LocalTemplateInfo.rect_Bottom) * 2;
                    Console.WriteLine("x: " + x_Inside.ToString() + "  y: " + y_Inside.ToString() + "  x&y: " + (x_Inside & y_Inside).ToString());
                    if (!(x_Inside & y_Inside))
                    {
                        isInsideRect = false;
                        break;
                    }
                    else
                    {
                        isInsideRect = true;
                    }
                }
                inside.Add(isInsideRect);
            }


            for (int i = 0; i < inside.Count; i++)
            {
                if (inside[i])
                {
                    mainInfos.Add(currConfigs[i].text);
                    finalPointList.Add(pointsList[i]);
                }
            }
            Console.WriteLine("框选信息个数：" + mainInfos.Count);
            for (int i = 0; i < mainInfos.Count; i++)
            {
                Console.WriteLine("框选信息内容" + i + "：" + mainInfos[i]);
            }
            Console.WriteLine("点位个数：" + finalPointList.Count);
        }
 
        public static Image RectPoints(Image Image, List<List<Point>> pointsList)
        {
            //Bitmap bitmap = new Bitmap(Camera_Form.frameForSave.Image.ToBitmap());

            Graphics graphics1 = Graphics.FromImage(Image);

            Pen pen = new Pen(Color.Green, 5);
            //foreach (var item in pointsList.ToArray())
            //{
            //    graphics1.DrawLines(pen, item.ToArray());
            //    graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            //}
            for (int i = 0; i < pointsList.Count; i++)
            {
                graphics1.DrawLines(pen, pointsList[i].ToArray());
                graphics1.DrawLine(pen, pointsList[i].ToArray()[0], pointsList[i].ToArray()[3]);
            }
            graphics1.Dispose();

            return Image;
        }

        private static int SaveImage(ImageFormatInfo imageFormatInfo)
        {
            if (CameraReceiveThread.frameForSave == null)
            {
                throw new Exception("No vaild image");
            }
            string imagePath = "Image_w" + CameraReceiveThread.frameForSave.Image.Width.ToString() + "_h" + CameraReceiveThread.frameForSave.Image.Height.ToString() + "_fn" + CameraReceiveThread.frameForSave.FrameNum.ToString() + "." + imageFormatInfo.FormatType.ToString();

            lock (CameraReceiveThread.saveImageLock)
            {
                return CameraReceiveThread.device.ImageSaver.SaveImageToFile(imagePath, CameraReceiveThread.frameForSave.Image, imageFormatInfo, CFAMethod.Optimal);
            }
        }
        public static void SaveBmp()
        {
            int result;

            try
            {
                ImageFormatInfo imageFormatInfo = new ImageFormatInfo();
                imageFormatInfo.FormatType = ImageFormatType.Bmp;

                result = SaveImage(imageFormatInfo);
                if (result != MvError.MV_OK)
                {
                    CameraReceiveThread.ShowErrorMsg("Save Image Fail!", result);
                    return;
                }
                else
                {
                    CameraReceiveThread.ShowErrorMsg("Save Image Succeed!", 0);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Save Image Failed, " + ex.Message);
                return;
            }







        }

        public static void SaveWrongImg(IFrameOut ImageOriginal)
        {
            IFrameOut imageOriginal = ImageOriginal;
            

            if (OCR_Form.isSaveImg)
            {
                try
                {
                    ImageOriginal.Image.ToBitmap().Save(@"out\\" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".bmp");
                }
                catch (Exception e)
                {
                    //throw (e);
                }
            }
            if (CameraTriggerTime_Config.SaveOriginalImageCh)
            {
                Console.WriteLine("存原图");
                try
                {
                    string outImgPath = Application.StartupPath + "\\out\\";
                    string tempPath = outImgPath + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
                    Console.WriteLine(Directory.Exists(tempPath));
                    if (!Directory.Exists(tempPath))
                    {
                        Directory.CreateDirectory(tempPath);
                    }
                    ImageFormatInfo imageFormatInfo = new ImageFormatInfo();
                    imageFormatInfo.FormatType = ImageFormatType.Bmp;
                    string ImagePath = tempPath + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_Original" + ".bmp";
                    CameraReceiveThread.device.ImageSaver.SaveImageToFile(ImagePath, ImageOriginal.Image, imageFormatInfo, CFAMethod.Equilibrated);
                }
                catch (Exception ex)
                {
                    //throw (ex);
                }
            }

            //return ImageOriginal.Image.ToBitmap();
        }


        public static void ImageHandleV2_Opencv(string path)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            //System.Drawing.Bitmap bitmap = new Bitmap(path);

            Console.WriteLine("OpenCvSharp");

            OpenCvSharp.Mat src = OpenCvSharp.Cv2.ImRead(path, OpenCvSharp.ImreadModes.Color);
            if (src.Empty())
            {
                Console.WriteLine("无法加载图像，请检查路径是否正确。");
                return;
            }

            IntPtr resultPtr = do_ocr_Mat(src.CvPtr);
            if (resultPtr == IntPtr.Zero)
                return;

            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;


            //RectPoints(bitmap);
        }

        public static Image ImageHandleV2_Opencv(Bitmap bitmap, Rectangle cropArea, float scale = 1)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            //System.Drawing.Bitmap bitmap = new Bitmap(path);

            Console.WriteLine("OpenCvSharp_bitmap");

            //OpenCvSharp.Mat src = OpenCvSharp.Cv2.ImRead(path, OpenCvSharp.ImreadModes.Color);
            //OpenCvSharp.Mat src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);

            //Bitmap zoomBit = SafeScaleBitmapZoomOut_R_Img(bitmap, 2);

            DateTime dt1 = DateTime.Now;

            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Jpeg);  // 支持PNG、BMP等格式
            byte[] bytes = ms.ToArray();
            ms.Dispose();
            OpenCvSharp.Mat src = OpenCvSharp.Mat.FromImageData(bytes);
            OpenCvSharp.Cv2.Resize(src, src, new OpenCvSharp.Size(src.Cols / scale, src.Rows / scale), (double)OpenCvSharp.InterpolationFlags.Linear);
            //OpenCvSharp.Mat src1 = OpenCvSharp.Mat.FromImageData(bytes);
            //OpenCvSharp.Mat src2 = OpenCvSharp.Mat.FromImageData(bytes);
            //OpenCvSharp.Cv2.Resize(src1, src1, new OpenCvSharp.Size(src.Cols  / 2, src.Rows  / 2), (double)OpenCvSharp.InterpolationFlags.Linear);
            //string dateTime = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
            //src1.SaveImage(dateTime+"_2_Resize.bmp");
            //OpenCvSharp.Cv2.Resize(src2, src2, new OpenCvSharp.Size(src.Cols / 2.5, src.Rows / 2.5), (double)OpenCvSharp.InterpolationFlags.Linear);
            //string dateTime1 = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
            //src2.SaveImage(dateTime1 + "_2.5_Resize.bmp");
            if (src.Empty())
            {
                Console.WriteLine("无法加载图像，请检查路径是否正确。");
                return null ;
            }

            IntPtr resultPtr = do_ocr_Mat(src.CvPtr);
            if (resultPtr == IntPtr.Zero)
                return null;
            DateTime dt2 = DateTime.Now;
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point((int)(configs[i].box[j][0]*scale), (int)(configs[i].box[j][1] * scale));
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;
            convertList = ConvertPointList(pointsList, cropArea);
           
            return bitmap;
            //RectPoints(bitmap);
        }

        #region 缩放
        public static List<List<Point>> convertList = new List<List<Point>>();
        //获取图片数据缩放后进算法
        public static Image ImageHandleV2_Zoom(Bitmap bitmap, Rectangle cropArea, int scale = 2)
        {
            pointsList.Clear();

            byte[] imageData = SafeScaleBitmapZoomOut(bitmap, scale);
            IntPtr resultPtr = do_ocr(imageData, bitmap.Width / scale, bitmap.Height / scale);

            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0] * scale, configs[i].box[j][1] * scale);
                    //Console.WriteLine(point.X+"  "+point.Y);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;
            convertList = ConvertPointList(pointsList, cropArea);


            return bitmap;
        }

        //new Rectangle(x: 218, y: 530, width: 748, height: 310)

        //获取图片数据缩放
        private static byte[] SafeScaleBitmapZoomOut(Bitmap srcBmp, int scale)
        {

            // 1. 加载源图像
            //Bitmap srcBmp = new Bitmap(path);

            int channels = Image.GetPixelFormatSize(srcBmp.PixelFormat) / 8;
            Console.WriteLine(channels);
            // 2. 创建目标图像（示例缩放为50%）
            int newWidth = srcBmp.Width / scale;
            int newHeight = srcBmp.Height / scale;
            Bitmap dstBmp = new Bitmap(newWidth, newHeight, srcBmp.PixelFormat);

            // 3. 获取像素数据
            var srcData = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height),
                ImageLockMode.ReadOnly, srcBmp.PixelFormat);
            var dstData = dstBmp.LockBits(new Rectangle(0, 0, newWidth, newHeight),
                ImageLockMode.WriteOnly, dstBmp.PixelFormat);

            // 4. 创建托管缓冲区
            byte[] srcBuffer = new byte[srcData.Stride * srcBmp.Height];
            byte[] dstBuffer = new byte[dstData.Stride * newHeight];
            Marshal.Copy(srcData.Scan0, srcBuffer, 0, srcBuffer.Length);

            // 5. 执行安全缩放（双线性插值）
            SafeBilinearScale(srcBuffer, dstBuffer,
                srcBmp.Width, srcBmp.Height,
                newWidth, newHeight,
                channels);

            // 6. 写回并显示
            //Marshal.Copy(dstBuffer, 0, dstData.Scan0, dstBuffer.Length);
            srcBmp.UnlockBits(srcData);
            dstBmp.UnlockBits(dstData);

            return dstBuffer;
            //picResult.Image = dstBmp;
        }
        //图片数据缩放
        private static void SafeBilinearScale(byte[] src, byte[] dst,
    int srcWidth, int srcHeight,
    int dstWidth, int dstHeight,
    int channels)
        {
            float xRatio = (float)srcWidth / dstWidth;
            float yRatio = (float)srcHeight / dstHeight;
            int srcStride = srcWidth * channels;

            for (int y = 0; y < dstHeight; y++)
            {
                float srcY = y * yRatio;
                int y0 = (int)srcY;
                int y1 = Math.Min(y0 + 1, srcHeight - 1);
                float wy = srcY - y0;

                for (int x = 0; x < dstWidth; x++)
                {
                    float srcX = x * xRatio;
                    int x0 = (int)srcX;
                    int x1 = Math.Min(x0 + 1, srcWidth - 1);
                    float wx = srcX - x0;

                    // 获取四个相邻像素的索引
                    int i00 = (y0 * srcWidth + x0) * channels;
                    int i01 = (y0 * srcWidth + x1) * channels;
                    int i10 = (y1 * srcWidth + x0) * channels;
                    int i11 = (y1 * srcWidth + x1) * channels;

                    // 计算目标像素索引
                    int dstIndex = (y * dstWidth + x) * channels;

                    for (int c = 0; c < channels; c++)
                    {
                        // 双线性插值计算
                        float v00 = src[i00 + c];
                        float v01 = src[i01 + c];
                        float v10 = src[i10 + c];
                        float v11 = src[i11 + c];

                        float top = v00 * (1 - wx) + v01 * wx;
                        float bottom = v10 * (1 - wx) + v11 * wx;
                        dst[dstIndex + c] = (byte)(top * (1 - wy) + bottom * wy);
                    }
                }
            }
        }
        /// <summary>
        /// 点位数组List全部转换
        /// </summary>
        /// <param name="pointList">点位数组List</param>
        /// <param name="cropArea">框选区域</param>
        /// <returns></returns>
        public static List<List<Point>> ConvertPointList(List<List<Point>> pointList, Rectangle cropArea)
        {
            List<List<Point>> tempList = new List<List<Point>>();
            for (int i = 0; i < pointList.Count; i++)
            {
                tempList.Add(ConvertPointsToOriginal(pointList[i].ToArray(), cropArea).ToList());
            }

            return tempList;
        }
        //点位数组转换为原图点位
        private static Point[] ConvertPointsToOriginal(Point[] croppedPoints, Rectangle cropArea)
        {
            Point[] points = croppedPoints.Select(p => new Point(
                  p.X + cropArea.X,
                  p.Y + cropArea.Y
              )).ToArray();
            foreach (var item in points)
            {
                //Console.WriteLine("Convert: "+"x;"+item.X+"   "+"y:" + item.Y);
            }
            return points;

        }

        //裁剪原图，截取框选区域
        public static Image CropImage(Bitmap originalImage, Rectangle cropArea, string outputPath = "")
        {
            // 加载原始图片
            using (originalImage)
            {
                // 检查裁剪区域是否有效
                if (cropArea.X < 0 || cropArea.Y < 0 ||
                    cropArea.Width <= 0 || cropArea.Height <= 0 ||
                    cropArea.Right > originalImage.Width ||
                    cropArea.Bottom > originalImage.Height)
                {
                    throw new ArgumentException("Invalid crop area");
                }

                // 创建目标位图
                using (var croppedImage = new Bitmap(cropArea.Width, cropArea.Height))
                {
                    // 创建绘图对象
                    using (var graphics = Graphics.FromImage(croppedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        // 绘制裁剪区域
                        graphics.DrawImage(
                            originalImage,
                            new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                            cropArea,
                            GraphicsUnit.Pixel
                        );
                    }
                    Bitmap bitmap = ConvertTo8bpp(croppedImage);

                    ImageHandleV2_Zoom(bitmap, cropArea, 2);

                    if (outputPath != "")
                    {
                        bitmap.Save(outputPath, originalImage.RawFormat);
                    }

                    // 保存图片
                    //croppedImage.Save(outputPath, originalImage.RawFormat);

                    return RectPoints(originalImage, convertList);
                }
            }
        }
        public static Image CropImageNoRect(Bitmap originalImage, Rectangle cropArea, string outputPath = "")
        {
            // 加载原始图片
            using (originalImage)
            {
                // 检查裁剪区域是否有效
                if (cropArea.X < 0 || cropArea.Y < 0 ||
                    cropArea.Width <= 0 || cropArea.Height <= 0 ||
                    cropArea.Right > originalImage.Width ||
                    cropArea.Bottom > originalImage.Height)
                {
                    throw new ArgumentException("Invalid crop area");
                }

                // 创建目标位图
                using (var croppedImage = new Bitmap(cropArea.Width, cropArea.Height))
                {
                    // 创建绘图对象
                    using (var graphics = Graphics.FromImage(croppedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        // 绘制裁剪区域
                        graphics.DrawImage(
                            originalImage,
                            new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                            cropArea,
                            GraphicsUnit.Pixel
                        );
                    }
                    Bitmap bitmap = ConvertTo8bpp(croppedImage);

                    //ImageHandleV2_Zoom(bitmap, cropArea, 2);

                    if (outputPath != "")
                    {
                        bitmap.Save(outputPath, originalImage.RawFormat);
                    }

                    // 保存图片
                    //croppedImage.Save(outputPath, originalImage.RawFormat);

                    return ImageHandleV2_Zoom(bitmap, cropArea, 2);
                }
            }
        }
        //转为8位像素  （使用Graphics重新画图像（包括裁剪）时，不能创建8位像素的对象，画完图后转为8位像素）
        public static Bitmap ConvertTo8bpp(Bitmap original)
        {
            // 创建目标 8bpp 位图
            Bitmap target = new Bitmap(
                original.Width,
                original.Height,
                PixelFormat.Format8bppIndexed
            );

            // 设置灰度调色板（典型 8bpp 调色板）
            ColorPalette palette = target.Palette;
            for (int i = 0; i < 256; i++)
            {
                palette.Entries[i] = Color.FromArgb(i, i, i);
            }
            target.Palette = palette;

            // 锁定位图数据
            BitmapData originalData = original.LockBits(
                new Rectangle(0, 0, original.Width, original.Height),
                ImageLockMode.ReadOnly,
                original.PixelFormat
            );

            BitmapData targetData = target.LockBits(
                new Rectangle(0, 0, target.Width, target.Height),
                ImageLockMode.WriteOnly,
                target.PixelFormat
            );

            try
            {
                // 手动转换像素（简单亮度公式）
                unsafe
                {
                    byte* targetPtr = (byte*)targetData.Scan0;
                    int* originalPtr = (int*)originalData.Scan0;

                    for (int i = 0; i < original.Height; i++)
                    {
                        for (int j = 0; j < original.Width; j++)
                        {
                            int pixel = originalPtr[j];
                            // 亮度公式：0.299*R + 0.587*G + 0.114*B
                            byte brightness = (byte)(
                                (pixel & 0xFF) * 0.114 +         // B
                                ((pixel >> 8) & 0xFF) * 0.587 +  // G
                                ((pixel >> 16) & 0xFF) * 0.299   // R
                            );
                            targetPtr[j] = brightness;
                        }
                        targetPtr += targetData.Stride;
                        originalPtr += originalData.Stride / 4;
                    }
                }
            }
            finally
            {
                original.UnlockBits(originalData);
                target.UnlockBits(targetData);
            }

            return target;
        }

        public static Image CropImageNoRect_opencv(Bitmap originalImage, Rectangle cropArea, string outputPath = "")
        {
            // 加载原始图片
            using (originalImage)
            {
                // 检查裁剪区域是否有效
                if (cropArea.X < 0 || cropArea.Y < 0 ||
                    cropArea.Width <= 0 || cropArea.Height <= 0 ||
                    cropArea.Right > originalImage.Width ||
                    cropArea.Bottom > originalImage.Height)
                {
                    Console.WriteLine("裁剪内部--裁剪区域无效");
                    return null;
                    //throw new ArgumentException("Invalid crop area");
                }

                // 创建目标位图
                using (var croppedImage = new Bitmap(cropArea.Width, cropArea.Height))
                {
                    // 创建绘图对象
                    using (var graphics = Graphics.FromImage(croppedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        // 绘制裁剪区域
                        graphics.DrawImage(
                            originalImage,
                            new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                            cropArea,
                            GraphicsUnit.Pixel
                        );
                    }
                    Bitmap bitmap = ConvertTo8bpp(croppedImage);

                    //ImageHandleV2_Zoom(bitmap, cropArea, 2);

                    if (outputPath != "")
                    {
                        bitmap.Save(outputPath, originalImage.RawFormat);
                    }

                    Image bitmap1 = ImageHandleV2_Opencv(bitmap, cropArea);

                    if (bitmap1 == null)
                    {
                        Console.WriteLine("图像为Null");
                        return null;
                    }


                    // 保存图片
                    //croppedImage.Save(outputPath, originalImage.RawFormat);
                    originalImage.Dispose();
                    return bitmap1;
                }
            }
        }
        public static Image CropImageNoRect_opencv_nousing(Bitmap originalImage, Rectangle cropArea, string outputCropPath = "", string outputZoomPath = "",float scale=1)
        {
            DateTime dt_Crop_in = DateTime.Now;
            // 检查裁剪区域是否有效
            if (cropArea.X < 0 || cropArea.Y < 0 ||
                cropArea.Width <= 0 || cropArea.Height <= 0 ||
                cropArea.Right > originalImage.Width ||
                cropArea.Bottom > originalImage.Height)
            {
                Console.WriteLine("裁剪内部--裁剪区域无效");
                return null;
                //throw new ArgumentException("Invalid crop area");
            }
            // 创建目标位图
            var croppedImage = new Bitmap(cropArea.Width, cropArea.Height);
            // 创建绘图对象
            var graphics = Graphics.FromImage(croppedImage);

            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            // 绘制裁剪区域
            graphics.DrawImage(
                originalImage,
                new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                cropArea,
                GraphicsUnit.Pixel
            );
            DateTime dt_Crop_out = DateTime.Now;
            //Bitmap bitmap = ConvertTo8bpp(croppedImage);
            DateTime dt_Crop_out_Convert = DateTime.Now;
            //ImageHandleV2_Zoom(bitmap, cropArea, 2);

            if (outputCropPath != "")
            {
                //bitmap.Save(outputCropPath, originalImage.RawFormat);
            }

            //c#方法缩放
            //Bitmap zoomBit = ResizeImage(bitmap, scale);
            //if (outputZoomPath != "")
            //{
            //    zoomBit.Save(outputZoomPath, originalImage.RawFormat);
            //}
            //Image bitmap1 = ImageHandleV2_Opencv(zoomBit, cropArea, scale);

            //opencv方法缩放
            Image bitmap1 = ImageHandleV2_Opencv(croppedImage, cropArea, scale);
            //Image bitmap1 = ImageHandleV2_Opencv(bitmap, cropArea,2.5f);
            DateTime dt_Crop_out_Convert_outA = DateTime.Now;

            Console.WriteLine("裁剪时长："+(dt_Crop_out- dt_Crop_in).TotalMilliseconds
                +"  转换8位时长:  "+ (dt_Crop_out_Convert - dt_Crop_out).TotalMilliseconds
                + "  算法时长:  " + (dt_Crop_out_Convert_outA - dt_Crop_out_Convert).TotalMilliseconds
                + "  总时长:  " + (dt_Crop_out_Convert_outA - dt_Crop_in).TotalMilliseconds);
            if (bitmap1 == null)
            {
                Console.WriteLine("图像为Null");
                return null;
            }


            // 保存图片
            //croppedImage.Save(outputPath, originalImage.RawFormat);
            //originalImage.Dispose();
            return bitmap1;


        }
        public static Bitmap ResizeImage(Image originalImage, int scaleFactor)
        {
            // 计算新的尺寸（宽度和高度都缩小 scaleFactor 倍）
            int newWidth = originalImage.Width / scaleFactor;
            int newHeight = originalImage.Height / scaleFactor;

            Bitmap bitmap = new Bitmap(newWidth, newHeight);
            Bitmap resizedImage = new Bitmap(newWidth, newHeight);
            Graphics graphics = Graphics.FromImage(resizedImage);
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight);

            bitmap = ConvertTo8bpp(resizedImage);

            //bitmap.Save("Resize.bmp");

            return bitmap;
        }
        #endregion

        public static void ImageHandleV2_CropImg(Bitmap originalImage, Rectangle cropArea, string outputCropPath = "")
        {
            DateTime dt_Crop_in = DateTime.Now;
            bool t1 = cropArea.Right > originalImage.Width;
            bool t2 = cropArea.Bottom > originalImage.Height;
            Console.WriteLine("cropArea.X :"+ cropArea.X + "  cropArea.Y :" + cropArea.Y 
                + "  cropArea.Width :" + cropArea.Width + "  cropArea.Height :" + cropArea.Height 
                + "  cropArea.Right :" + cropArea.Right + "  cropArea.Bottom :" + cropArea.Bottom
                + "  originalImage.Right :" + originalImage.Width + "  originalImage.Height :" + originalImage.Height
                + "  cropArea.Right > originalImage.Width："+ t1
                + "  cropArea.Bottom > originalImage.Height：" + t2);
            // 检查裁剪区域是否有效
            if (cropArea.X < 0 || cropArea.Y < 0 ||
                cropArea.Width <= 0 || cropArea.Height <= 0 ||
                cropArea.Right > originalImage.Width ||
                cropArea.Bottom > originalImage.Height)
            {
                Console.WriteLine("裁剪内部--裁剪区域无效");
                //return null;
                //throw new ArgumentException("Invalid crop area");
            }
            Console.WriteLine(cropArea.Size);
            // 创建目标位图
            var croppedImage = new Bitmap(cropArea.Width, cropArea.Height);
            // 创建绘图对象
            var graphics = Graphics.FromImage(croppedImage);

            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            // 绘制裁剪区域
            graphics.DrawImage(
                originalImage,
                new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                cropArea,
                GraphicsUnit.Pixel
            );
            DateTime dt_Crop_out = DateTime.Now;
            //originalImage.Dispose();
            Bitmap bitmap = ConvertTo8bpp(croppedImage);
            if (outputCropPath != "")
            {
                //Console.WriteLine("outputCropPath:"+ bitmap.Size);
                bitmap.Save(outputCropPath);
                //bitmap.Dispose();
                //graphics.Dispose();
            }

            ImageHandleV2_Crop(bitmap, cropArea);
        }

        public static void ImageHandleV2_Crop(Bitmap bitmap, Rectangle cropArea)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            //System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;            

            convertList = ConvertPointList(pointsList, cropArea);
            LocalCompare(convertList);

        }
    }
}
